#include "head.h"

/* Usage:  ./main*/
// 定义管道自己给自己通信
int pipefd[2];

void func(int num)
{
    // printf("main num:%d\n", num);
    write(pipefd[1], "1", 1);
}
int main(void){                                  

    // 启动子进程
    son_status_t list[4];
    initPoll(list, 4);

    pipe(pipefd);
    signal(2, func);

    // 初始化网络监听连接
    // bind和listen
    int socket_fd;
    initSocket(&socket_fd, "192.168.229.128", "8080");

    // 初始化epoll，获得epoll对象
    int epoll_fd = epoll_create(1);
    // 放入监听，建立三次握手，和本地socket进行通信
    addEpoll(epoll_fd, socket_fd);
    for(int i=0; i<4; i++)
    {
        addEpoll(epoll_fd, list[i].local_socket);
    }

    // 监听管道的读端
    addEpoll(epoll_fd, pipefd[0]);

    while(1)
    {
        // 就绪集合
        struct epoll_event events[10];
        memset(events, 0, sizeof(events));
        // 监听就绪集合
        int epoll_num = epoll_wait(epoll_fd, events, 10, -1);

        for(int i=0; i<epoll_num; i++)
        {
            int fd = events[i].data.fd;

            // 管道可读，说明有信号到来
            if(fd == pipefd[0])
            {
                char buf[60] = {0};
                read(fd, buf, sizeof(buf));

                // 父进程接收到信号，要求退出，退出之前，先通知子进程
                // 通知子进程通过本地socket
                for(int j=0; j<4; j++)
                {
                    sendMsg(list[j].local_socket, 1, -1);
                }

                // 等待子进程退出父进程再退出
                for(int k=0; k<4; k++)
                {
                    wait(NULL);
                }

                // 走到这里，子进程已全部退出
                printf("子进程已退出，父进程也开始退出！ \n");

                // TODO:close free ....
                exit(0);
            }
            else if(fd == socket_fd)
            {
                // 有新链接进来
                int net_fd = accept(socket_fd, NULL, NULL);

                // 把这个新链接对象交给空闲的子进程
                toSonNetFd(list, 4, net_fd);

                // 就算关闭还是会发送数据完成
                close(net_fd);
                continue;
            }
            // 某个字进程完成任务，子进程通过本地socket发回信息
            // 导致epoll监听对应本地socket就绪
            for(int j=0; j<4; j++)
            {
                // 就绪集合中是否有本地socket就绪
                // 如果就绪表明子进程 已经空闲
                if(fd == list[j].local_socket)
                {
                    // 接收子进程发过来的信息 变为闲状态
                    char buf[60] = { 0 };
                    recv(fd, buf, sizeof(buf), 0);
                    // 说明由忙变为闲
                    list[j].flag = FREE;
                    continue;

                }
            }
        }
    }

    return 0;
}


